import {type Ref} from 'vue'
import type InputProps from "@/components/input/type/InputProps.ts";
import type InputEmits from "@/components/input/type/InputEmits.ts";

/**
 * created by yangtong on 2025/6/16 下午11:02
 * <br />
 * 输入框事件处理逻辑
 */
export function useInputEvents(
    props: InputProps,
    emit: InputEmits,
    state: {
        errorMessage: Ref<string>
        displayValue: Ref<string>
        focused: Ref<boolean>
        isComposing: Ref<boolean>
        normalizedModelValue: Ref<string>
    },
    helpers: {
        allowsCheck: (val: string) => boolean
        validate: () => boolean
        formatValue: (val: string | number | null | undefined) => string
    }
) {

    const functionalKeys = [
        'Backspace', 'Delete', 'Tab', 'Enter'
    ]

    // 焦点事件
    const onFocus = (e: FocusEvent) => {
        state.errorMessage.value = ''
        state.displayValue.value = state.normalizedModelValue.value
        state.focused.value = true
        emit("focus", e)
    }

    const onBlur = (e: FocusEvent) => {
        state.focused.value = false

        if (state.normalizedModelValue.value.length > 0) {
            state.displayValue.value = helpers.formatValue(props.modelValue)
        }

        helpers.validate()
        emit("blur", e)
    }

    // 输入法事件
    const onCompositionstart = () => {
        state.isComposing.value = true
    }

    const onCompositionend = (event: Event) => {
        state.isComposing.value = false
        onInput(event)
    }

    // 输入事件
    const onInput = (event: Event) => {
        if (state.isComposing.value) return

        const target = event.target as HTMLInputElement
        let val = target.value

        // 解析输入值
        if (props.parse) {
            val = props.parse(val)
        }

        // 检查是否允许输入
        if (!helpers.allowsCheck(val)) {
            target.value = state.displayValue.value ?? ""
            return
        }

        // 根据输入框类型决定输出类型
        const outputValue = props.type === 'number' && val !== ''
            ? (isNaN(Number(val)) ? val : Number(val))
            : val

        emit("update:modelValue", outputValue)
        emit("input", val, event)
        state.displayValue.value = val
    }

    // 键盘事件
    const onKeydown = (e: KeyboardEvent) => {
        // 允许快捷键和功能键
        if (e.ctrlKey || e.metaKey || e.altKey) {
            emit("keydown", e)
            return
        }

        if (!e.key) {
            return;
        }

        if (functionalKeys.includes(e.key) || e.key.startsWith('Arrow')) {
            emit("keydown", e)
            return
        }

        // 字符级校验
        if (!helpers.allowsCheck(e.key)) {
            e.preventDefault()
            return
        }

        emit("keydown", e)
    }

    const onKeyup = (e: KeyboardEvent) => {
        emit("keyup", e)
    }

    // 粘贴事件
    const onPaste = (e: ClipboardEvent) => {
        const pasteData = e.clipboardData?.getData('text') ?? ""
        if (!helpers.allowsCheck(pasteData)) {
            e.preventDefault()
        }
    }

    return {
        onFocus,
        onBlur,
        onCompositionstart,
        onCompositionend,
        onInput,
        onKeydown,
        onKeyup,
        onPaste
    }

}